home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / TCPCMD.C < prev    next >
C/C++ Source or Header  |  1990-07-31  |  8KB  |  372 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9.  
  10. /* TCP connection states */
  11. char *tcpstates[] = {
  12.     "Closed",
  13.     "Listen",
  14.     "SYN sent",
  15.     "SYN rcvd",
  16.     "Established",
  17.     "FIN wait 1",
  18.     "FIN wait 2",
  19.     "Close wait",
  20.     "Closing",
  21.     "Last ACK",
  22.     "Time wait"
  23. };
  24.  
  25. /* TCP closing reasons */
  26. char *reasons[] = {
  27.     "Normal",
  28.     "Reset",
  29.     "Timeout",
  30.     "ICMP"
  31. };
  32. /* TCP subcommand table */
  33. static int domss(),doirtt(),dortt(),dotcpstat(),dowindow(),dotcpkick(),
  34.     dobackoff(),dotcpclose(),dotcpreset(),dotcptimout(),dotcptos(),tstat();
  35. struct cmds tcpcmds[] = {
  36.     "active",    tstat,        0,    NULLCHAR,    NULLCHAR,
  37.     "backoff",    dobackoff,    3,    "<tcb> <val>",    NULLCHAR,
  38.     "close",    dotcpclose,    2,    "<tcb>",    NULLCHAR,
  39.     "irtt",        doirtt,        0,    NULLCHAR,    NULLCHAR,
  40.     "kick",        dotcpkick,    2,    "<tcb>",    NULLCHAR,
  41.     "mss",        domss,        0,    NULLCHAR,    NULLCHAR,
  42.     "reset",    dotcpreset,    2,    "<tcb>",    NULLCHAR,
  43.     "rtt",        dortt,        3,    "<tcb> <val>",    NULLCHAR,
  44.     "status",    dotcpstat,    0,    NULLCHAR,    NULLCHAR,
  45.     "timeout",    dotcptimout,    0,    NULLCHAR,    NULLCHAR,
  46.     "tos",        dotcptos,    3,    "<tcb> <tos>",    NULLCHAR,
  47.     "window",    dowindow,    0,    NULLCHAR,    NULLCHAR,
  48.     NULLCHAR,    NULLFP,        0,    "?subcommands", NULLCHAR
  49. };
  50. int
  51. dotcp(argc,argv)
  52. int argc;
  53. char *argv[];
  54. {
  55.     return subcmd(tcpcmds,argc,argv);
  56. }
  57.  
  58. /* Close a TCP connection */
  59. static int
  60. dotcpclose(argc,argv)
  61. int argc;
  62. char *argv[];
  63. {
  64.     register struct tcb *tcb;
  65.     extern char notval[];
  66.  
  67.     tcb = (struct tcb *)long2ptr(htol(argv[1]));
  68.     if(!tcpval(tcb)){
  69.         printf(notval);
  70.         return 1;
  71.     }
  72.     close_tcp(tcb);
  73.     return 0;
  74. }
  75.  
  76. /* Eliminate a TCP connection */
  77. static int
  78. dotcpreset(argc,argv)
  79. int argc;
  80. char *argv[];
  81. {
  82.     register struct tcb *tcb;
  83.     extern char notval[];
  84.  
  85.     tcb = (struct tcb *)long2ptr(htol(argv[1]));
  86.     if(!tcpval(tcb)){
  87.         printf(notval);
  88.         return 1;
  89.     }
  90.     close_self(tcb,RESET);
  91.     return 0;
  92. }
  93.  
  94. /* Set initial round trip time for new connections */
  95. static int
  96. doirtt(argc,argv)
  97. int argc;
  98. char *argv[];
  99. {
  100.     if(argc < 2)
  101.         printf("%lu\n",tcp_irtt);
  102.     else
  103.         tcp_irtt = atol(argv[1]);
  104.     return 0;
  105. }
  106.  
  107. /* Set backoff for specified TCB */
  108. static int
  109. dobackoff(argc,argv)
  110. int argc;
  111. char *argv[];
  112. {
  113.     register struct tcb *tcb;
  114.     extern char notval[];
  115.  
  116.     tcb = (struct tcb *)long2ptr(htol(argv[1]));
  117.     if(!tcpval(tcb)){
  118.         printf(notval);
  119.         return 1;
  120.     }
  121.     tcb->backoff = atoi(argv[2]) & 0x7f;
  122.     return 0;
  123. }
  124.  
  125. /* Set smoothed round trip time for specified TCB */
  126. static int
  127. dortt(argc,argv)
  128. int argc;
  129. char *argv[];
  130. {
  131.     register struct tcb *tcb;
  132.     extern char notval[];
  133.  
  134.     tcb = (struct tcb *)long2ptr(htol(argv[1]));
  135.     if(!tcpval(tcb)){
  136.         printf(notval);
  137.         return 1;
  138.     }
  139.     tcb->srtt = atol(argv[2]);
  140.     return 0;
  141. }
  142.  
  143. /* Set TOS for specified TCB */
  144. static int
  145. dotcptos(argc,argv)
  146. int argc;
  147. char *argv[];
  148. {
  149.     register struct tcb *tcb;
  150.     extern char notval[];
  151.  
  152.     tcb = (struct tcb *)long2ptr(htol(argv[1]));
  153.     if(!tcpval(tcb)){
  154.         printf(notval);
  155.         return 1;
  156.     }
  157.     tcb->tos = (tcb->tos & 0xe0) | (get_tos(argv[2]) & 0x1f);
  158.     return 0;
  159. }
  160.  
  161. /* Force a retransmission */
  162. static int
  163. dotcpkick(argc,argv)
  164. int argc;
  165. char *argv[];
  166. {
  167.     register struct tcb *tcb;
  168.     extern char notval[];
  169.  
  170.     tcb = (struct tcb *)long2ptr(htol(argv[1]));
  171.     if(kick_tcp(tcb) == -1){
  172.         printf(notval);
  173.         return 1;
  174.     }
  175.     return 0;
  176. }
  177.  
  178. /* Set default maximum segment size */
  179. static int
  180. domss(argc,argv)
  181. int argc;
  182. char *argv[];
  183. {
  184.     if(argc < 2)
  185.         printf("%u\n",tcp_mss);
  186.     else
  187.         tcp_mss = atoi(argv[1]);
  188.     return 0;
  189. }
  190.  
  191. /* Set timeout for transient states */
  192. static int
  193. dotcptimout(argc,argv)
  194. int argc;
  195. char *argv[];
  196. {
  197.     if(argc < 2)
  198.         printf("%lu\n",TICK2SEC(tcp_timout));
  199.     else
  200.         tcp_timout = SEC2TICK(atol(argv[1]));
  201.     return 0;
  202. }
  203.  
  204. /* Set default window size */
  205. static int
  206. dowindow(argc,argv)
  207. int argc;
  208. char *argv[];
  209. {
  210.     if(argc < 2)
  211.         printf("%u\n",tcp_window);
  212.     else
  213.         tcp_window = atoi(argv[1]);
  214.     return 0;
  215. }
  216.  
  217. /* Display status of TCBs */
  218. static int
  219. dotcpstat(argc,argv)
  220. int argc;
  221. char *argv[];
  222. {
  223.     register struct tcb *tcb;
  224.     extern char notval[];
  225.  
  226.     if(argc < 2){
  227.         tstat(0);
  228.     } else {
  229.         tcb = (struct tcb *)long2ptr(htol(argv[1]));
  230.         if(tcpval(tcb))
  231.             state_tcp(tcb);
  232.         else
  233.             printf(notval);
  234.     }
  235.     return 0;
  236. }
  237.  
  238. /* Dump TCP stats and summary of all TCBs (or only non-SERVER TCBs)
  239.  *     &TCB Rcv-Q Snd-Q     Local socket        Remote socket           State
  240.  *     1234    0     0     xxx.xxx.xxx.xxx:xxxxx    xxx.xxx.xxx.xxx:xxxxx  Established
  241.  */
  242. static int
  243. tstat(no_server)
  244. int no_server;
  245. {
  246.     register int i;
  247.     register struct tcb *tcb;
  248.  
  249.     printf("conout %u conin %u reset out %u runt %u chksum err %u bdcsts %u\n",
  250.         tcp_stat.conout,tcp_stat.conin,tcp_stat.resets,tcp_stat.runt,
  251.         tcp_stat.checksum,tcp_stat.bdcsts);
  252.     printf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  253.     for(i=0;i<NTCB;i++){
  254.         for(tcb=tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  255.             if (no_server && tcb->state == LISTEN && (tcb->flags & CLONE))
  256.                 continue;        /* skip boring TCBs */
  257.  
  258.             printf("%8lx%6u%6u  ",ptr2long(tcb),tcb->rcvcnt,tcb->sndcnt);
  259.             printf("%-23s",psocket(&tcb->conn.local));
  260.             printf("%-23s",psocket(&tcb->conn.remote));
  261.             printf("%-s",tcpstates[tcb->state]);
  262.             if(tcb->state == LISTEN && (tcb->flags & CLONE))
  263.                 printf(" (S)");
  264.             printf("\n");
  265.         }
  266.     }
  267.     fflush(stdout);
  268.     return 0;
  269. }
  270. /* Dump a TCP control block in detail */
  271. static void
  272. state_tcp(tcb)
  273. struct tcb *tcb;
  274. {
  275.     int32 sent,recvd;
  276.  
  277.     if(tcb == NULLTCB)
  278.         return;
  279.     /* Compute total data sent and received; take out SYN and FIN */
  280.     sent = tcb->snd.una - tcb->iss; /* Acknowledged data only */
  281.     recvd = tcb->rcv.nxt - tcb->irs;
  282.     switch(tcb->state){
  283.     case LISTEN:
  284.     case SYN_SENT:        /* Nothing received or acked yet */
  285.         sent = recvd = 0;
  286.         break;
  287.     case SYN_RECEIVED:
  288.         recvd--;    /* Got SYN, no data acked yet */
  289.         sent = 0;
  290.         break;
  291.     case ESTABLISHED:    /* Got and sent SYN */
  292.     case FINWAIT1:        /* FIN not acked yet */
  293.         sent--;
  294.         recvd--;
  295.         break;
  296.     case FINWAIT2:        /* Our SYN and FIN both acked */
  297.         sent -= 2;
  298.         recvd--;
  299.         break;
  300.     case CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  301.     case CLOSING:
  302.     case LAST_ACK:
  303.         sent--;
  304.         recvd -= 2;
  305.         break;
  306.     case TIME_WAIT:        /* Sent and received SYN/FIN, all acked */
  307.         sent -= 2;
  308.         recvd -= 2;
  309.         break;
  310.     }
  311.     printf("Local: %s",psocket(&tcb->conn.local));
  312.     printf(" Remote: %s",psocket(&tcb->conn.remote));
  313.     printf(" State: %s",tcpstates[tcb->state]);
  314.     if (tcb->tos != 0)
  315.         printf(" TOS: %s",put_tos(tcb->tos));
  316.     printf("\n      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  317.     printf("Send:");
  318.     printf("%9lx",tcb->iss);
  319.     printf("%9lx",tcb->snd.una);
  320.     printf("%9lx",tcb->snd.nxt);
  321.     printf("%7lu",tcb->resent);
  322.     printf("%6u",tcb->cwind);
  323.     printf("%6u",tcb->ssthresh);
  324.     printf("%6u",tcb->snd.wnd);
  325.     printf("%5u",tcb->mss);
  326.     printf("%6u",tcb->sndcnt);
  327.     printf("%11lu\n",sent);
  328.  
  329.     printf("Recv:");
  330.     printf("%9lx",tcb->irs);
  331.     printf("         ");
  332.     printf("%9lx",tcb->rcv.nxt);
  333.     printf("%7lu",tcb->rerecv);
  334.     printf("      ");
  335.     printf("      ");
  336.     printf("%6u",tcb->rcv.wnd);
  337.     printf("     ");
  338.     printf("%6u",tcb->rcvcnt);
  339.     printf("%11lu\n",recvd);
  340.  
  341.     if(tcb->reseq != (struct reseq *)NULL){
  342.         register struct reseq *rp;
  343.  
  344.         printf("Reassembly queue:\n");
  345.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  346.             printf("  seq x%lx %u bytes\n",rp->seg.seq,rp->length);
  347.         }
  348.     }
  349.     if(tcb->backoff > 0)
  350.         printf("Backoff %u ",tcb->backoff);
  351.     if(tcb->flags & RETRAN)
  352.         printf("Retrying ");
  353.     switch(tcb->timer.state){
  354.     case TIMER_STOP:
  355.         printf("Timer stopped ");
  356.         break;
  357.     case TIMER_RUN:
  358.         printf("Timer running (%ld/%ld ms) ",
  359.              TICK2MS(tcb->timer.start - tcb->timer.count),
  360.              TICK2MS(tcb->timer.start));
  361.         break;
  362.     case TIMER_EXPIRE:
  363.         printf("Timer expired ");
  364.     }
  365.     printf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  366.     if(run_timer(&tcb->timeout))
  367.         printf("Watchdog timer running (%ld/%ld s)\n",
  368.              TICK2SEC(tcb->timeout.start - tcb->timeout.count),
  369.              TICK2SEC(tcb->timeout.start));
  370.     ffl